package prolog.fluents

import java.io._
import scala.collection.mutable._
import prolog.terms._
import prolog.io._

class DataBase(fname: String) extends LinkedHashMap[String, Queue[List[Term]]] {
  def this() = this(null)

  type CLAUSE = List[Term]
  if (null != fname) {
    fromFile(fname, true)
  } else
    initialize()

  private final def initialize() {
    clear()
    addAll((new TermParser()).parse(List(
      "eq(X,X). ",
      "answer_source(X0,G0,E):-copy_term(t(X0,G0),t(X,G)),new_engine([],X,G,E). ",
      "source_list(S,Xs):-source_to_list(yes,S,Xs). ",
      "findall(X,G,Xs):-answer_source(X,G,E),source_list(E,Xs). ",
      "listing:-listing(_). ",
      "[F]:-reconsult(F). ")))
  }

  final def fromFile(fname0: String, doClear: Boolean): Int = {
    val fname = fname0 + ".pro"
    if ((new File(fname)).exists()) {
      val parser = new TermParser()
      val cs = parser.file2clauses(fname)
      if (doClear) initialize()
      addAll(cs)
      1
    } else {
      println("file not found: " + fname)
      0
    }
  }

  def addAll(cs: List[CLAUSE]) {
    cs.foreach(add)
  }

  def key(c: CLAUSE) = c.head.ref.asInstanceOf[Const].sym

  def add(c: CLAUSE) {
    val k = key(c)
    val cs: Queue[CLAUSE] = get(k) match {
      case None => new Queue()
      case Some(xs) => xs
    }
    this.put(k, cs += c)
  }

  def matches(c: CLAUSE): Queue[CLAUSE] = {
    val k = key(c)
    get(k) match {
      case None => {
        println("*** call to undefined predicate: " + k)
        null
      }
      case Some(cs) => cs
    }
  }
}